package cc.realxyq.demo.scope;

import cc.realxyq.demo.util.ExecutorUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.core.NamedThreadLocal;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 自定义scope，其实就是 SimpleThreadScope 的实现
 * @author kwhan
 * @date 2022年01月07日 12:55
 */
@Slf4j
public class MyScope implements Scope {


    private static final ThreadLocal<Map<String, Object>> THREAD_SCOPE = new NamedThreadLocal<Map<String, Object>>("threadScope") {
        @Override
        protected Map<String, Object> initialValue() {
            return new HashMap<>(16);
        }
    };

    /**
     * 清理线程，主要针对线程池线程复用的情况，正常情况复用的线程不应该读取之前线程的数据，具体根据业务而定
     */
    public static void unload(){
        THREAD_SCOPE.remove();
    }


    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        Object bean = THREAD_SCOPE.get().get(name);
        if (Objects.isNull(bean)) {
            bean = objectFactory.getObject();
            THREAD_SCOPE.get().put(name, bean);
        }
        return bean;
    }

    @Override
    public Object remove(String name) {
        return THREAD_SCOPE.get().remove(name);
    }

    @Override
    public void registerDestructionCallback(String name, Runnable callback) {
        log.info("bean对象的名称：{}", name);
        ExecutorUtil.getExecutor().execute(callback);
    }

    @Override
    public Object resolveContextualObject(String key) {
        return null;
    }

    @Override
    public String getConversationId() {
        return Thread.currentThread().getName();
    }


}
